#include "writePositions.hpp"
#include "Log.hpp"
#include <cassert>
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#include <algorithm>
using namespace std;
using namespace m3g;


/**
 *
 */
unsigned int writePositions (M3GWriter* writer, MQObject mq_obj, float user_scale, float* scale_, float* bias_)
{
    assert (user_scale > 0);

	int vertex_count = mq_obj->GetVertexCount ();
	int face_count   = mq_obj->GetFaceCount ();

	float min_x = FLT_MAX, min_y = FLT_MAX, min_z = FLT_MAX;
	float max_x = FLT_MIN, max_y = FLT_MIN, max_z = FLT_MIN;
	for (int i = 0; i < (int)vertex_count; i++) {
		MQPoint p = mq_obj->GetVertex(i) * user_scale;
		min_x = min (min_x, p.x);
		min_y = min (min_y, p.y);
		min_z = min (min_z, p.z);
		max_x = max (max_x, p.x);
		max_y = max (max_y, p.y);
		max_z = max (max_z, p.z);
	}
	float max_len = max (max_x-min_x, max(max_y-min_y, max_z-min_z));

	float scale   = 65534/max_len;
	float bias[3] = {-32767*(max_x+min_x)/max_len,
					 -32767*(max_y+min_y)/max_len,
					 -32767*(max_z+min_z)/max_len};
	
    int component_count = 3;
    int component_size  = 2;

	M3GObject3DStruct    obj;
	M3GVertexArrayStruct varry;
	varry.component_size  = component_size;
	varry.component_count = component_count;
	varry.encoding        = M3GVertexArrayStruct::ENCODING_0;
	varry.vertex_count    = vertex_count;
	varry.short_components = new short*[vertex_count];
	for (int i = 0; i < (int)vertex_count; i++) {
		MQPoint p = mq_obj->GetVertex(i) * user_scale;
		varry.short_components[i]    = new short[3];
		varry.short_components[i][0] = (short)(p.x * scale + bias[0] + 0.5f);
		varry.short_components[i][1] = (short)(p.y * scale + bias[1] + 0.5f);
		varry.short_components[i][2] = (short)(p.z * scale + bias[2] + 0.5f);
	}

	unsigned int object_index;

	writer->startObject      (M3G_TYPE_VERTEX_ARRAY, &object_index);
	writer->writeObject3D    (obj);
	writer->writeVertexArray (varry);
	writer->endObject        ();

	*scale_  = 1/scale;
	bias_[0] = -bias[0]/scale;
	bias_[1] = -bias[1]/scale;
	bias_[2] = -bias[2]/scale;

   	Log:: print (" [%d] Write VertexArray(positions) :", object_index);
    Log:: print ("  vertex_count=%d"     , vertex_count   );
    Log:: print (", component_count=%d"  , component_count);
    Log:: print (", component_size=%d.\n", component_size );

	return object_index;
}
